package org.hackystat.devcathlon.ui.page.teams.manage;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.StatelessForm;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.form.validation.FormComponentFeedbackBorder;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.Model;
import org.hackystat.devcathlon.engine.team.Team;
import org.hackystat.devcathlon.engine.team.TeamException;
import org.hackystat.devcathlon.engine.team.TeamManager;
import org.hackystat.devcathlon.engine.user.User;
//import org.hackystat.devcathlon.engine.user.UserException;
import org.hackystat.devcathlon.engine.user.UserManager;
import org.hackystat.devcathlon.ui.DevcathlonApplication;
import org.hackystat.devcathlon.ui.DevcathlonSession;
import org.hackystat.sensorbase.client.SensorBaseClient;
import org.hackystat.sensorbase.client.SensorBaseClientException;
import org.hackystat.sensorbase.resource.projects.jaxb.Project;
import org.hackystat.sensorbase.resource.projects.jaxb.ProjectIndex;
import org.hackystat.sensorbase.resource.projects.jaxb.ProjectRef;

/**
 * The form for providing credentials to sign in to the Sensorbase. 
 * 
 * @author John Ly
 */
class CreateTeamForm extends StatelessForm {

  /** Support serialization. */
  private static final long serialVersionUID = 1L;
  /** The team name. */
  private String teamName = "";
  /** The description of the team. */
  private String description = "";
  /** The project name. */
  private String projectName = "";
  /** The team's logo file path. */
  private String logoPath = "";

  /**
   * Create this form, supplying the wicket:id.
   * 
   * @param id The wicket:id.
   */
  public CreateTeamForm(final String id) {
    super(id);
    setModel(new CompoundPropertyModel(this));  
    add(new FeedbackPanel("feedback"));
    add(new FormComponentFeedbackBorder("teamNameBorder")
          .add(new TextField("teamName")
             .setRequired(true)
             .setLabel(new Model("Team Name"))));         
    add(new FormComponentFeedbackBorder("projectNameBorder")
          .add(new DropDownChoice("projectName", getTeamsList())
                .setRequired(true)
                .setLabel(new Model("Project Name"))));    
    add(new TextArea("description"));
    add(new DropDownChoice("logoPath", getFilesAvailable()));
    //add(new TextField("logoPath"));
    
    //add(new FileUploadField("fileUploadField", new PropertyModel(this, "teamLogo")));
    //add(new FileUploadField("fileUploadField"));
  }
  
  /**
   * Process the user action after submitting a username/password.  Note that they will go 
   * to the page they requested if it was not the home page. 
   */
  @Override
  public void onSubmit() {    
      ((DevcathlonApplication)DevcathlonSession.get().getApplication()).getSensorBaseHost();
    String email = DevcathlonSession.get().getEmail();
    String password = DevcathlonSession.get().getPassword();

    try {
      // Retrieve the members of the specified project.       
      Project project = getProject(projectName);
      UserManager userManager = UserManager.getInstance();

      // Add all users to the UserManager in Devcathlon.
            
      User owner = userManager.getUser(email);
      if ( owner == null) {
        owner = userManager.addUser(email, "", email, password);
      }        
      else {
        userManager.getUser(email).updateCredentials(email, password);
      }
      
      Set<User> teamMembers = new HashSet<User>();
      for (String member : project.getMembers().getMember()) {      
        if (userManager.getUser(member) == null
              && !(email.equals(member))) {
          User teamMember = userManager.addUser(member, "", member, member);
          teamMembers.add(teamMember);
        }
        else if ( !(email.equals(member)) ) {
          teamMembers.add(userManager.getUser(member));
        }
      }      
      
      String projectOwner = project.getOwner();
      if (!(email.equals(projectOwner))) {
        if (userManager.getUser(projectOwner) == null) {          
          teamMembers.add(userManager.addUser(projectOwner, "", projectOwner, projectOwner));
        }
        else {
          teamMembers.add(userManager.getUser(projectOwner));
        }
      }
      
      // Create the Devcathlon team.
      Set<User> ownerAsMember = new HashSet<User>();
      ownerAsMember.add(owner);
      Team team = TeamManager.getInstance().addTeam(teamName, owner, ownerAsMember);
//      TeamManager.getInstance().getTeam(teamName).setProject(project);
      team.setProject(project);
//      TeamManager.getInstance().getTeam(teamName).setProjectName(projectName);
      team.setProjectName(projectName);
//      TeamManager.getInstance().getTeam(teamName).setDescription(description);
      team.setDescription(description);
//      TeamManager.getInstance().getTeam(teamName).setTeamLogoPath(logoPath);
      team.setTeamLogoPath(logoPath);
//      TeamManager.getInstance().getTeam(teamName).sendInvites(teamMembers);
      team.setInvited(teamMembers);
//      TeamManager.getInstance().setTeamInvites(teamName, teamMembers);
      TeamManager.getInstance().updateTeam(team);

      // Go back to TeamsManagePage.
      setResponsePage(new TeamsManagePage());
    }
//    catch (UserException e) {
//      ((DevcathlonApplication)this.getApplication()).getLogger().
//      info(e.getMessage());
//    }
    catch (TeamException e) {
      ((DevcathlonApplication)this.getApplication()).getLogger().
      info(e.getMessage());
    }      
  }

  /**
   * Gets all Hackystat projects associated with the user's email and 
   * returns a list of all projects owned by users.
   * @return The list of projects owned by the user.
   */
  private List<String> getTeamsList() {
    String host = 
      ((DevcathlonApplication)DevcathlonSession.get().getApplication()).getSensorBaseHost();
    String email = DevcathlonSession.get().getEmail();
    String password = DevcathlonSession.get().getPassword();
    
    List<String> teamNames = new ArrayList<String>();
    SensorBaseClient client = new SensorBaseClient(host, email, password);
    ProjectIndex projects;
    try {
      projects = client.getProjectIndex(email);
      for (ProjectRef ref : projects.getProjectRef()) {          
          teamNames.add(ref.getName());
      }
    }
    catch (SensorBaseClientException e) {      
      ((DevcathlonApplication)this.getApplication()).getLogger().
      info("Failed to retrieve projects from Hackystat for user: " + email);      
    }
    Collections.sort(teamNames);
    return teamNames;
  }
  
  /**
   * Retrieve the project instance from the sensorbase. 
   * @param name The name of the project.
   * @return The Project.
   */
  private Project getProject(String name) {
    String host = 
      ((DevcathlonApplication)DevcathlonSession.get().getApplication()).getSensorBaseHost();
    String email = DevcathlonSession.get().getEmail();
    String password = DevcathlonSession.get().getPassword();
    
    SensorBaseClient client = new SensorBaseClient(host, email, password);
    ProjectIndex projects;
    try {
      projects = client.getProjectIndex(email);
      for (ProjectRef ref : projects.getProjectRef()) {          
        if (name.equals(ref.getName())) {
          return client.getProject(ref);
        }
      }
    }
    catch (SensorBaseClientException e) {      
      ((DevcathlonApplication)this.getApplication()).getLogger().
      info("Failed to retrieve projects from Hackystat for user: " + email);      
    }
    
    return null;
  }
  
  /**
   * Returns the name of team.
   * @return The name of team.
   */
  public String getTeamName() {
    return this.teamName;
  }
  
  /**
   * Returns the description of team.
   * @return The description of team.
   */
  public String getDescription() {
    return this.description;
  }  
  
  /**
   * Sets the team name for the team.
   * @param teamName The team name.
   */
  public void setTeamName (String teamName) {
    this.teamName = teamName;
  }
  
  /**
   * Sets the team description/bio for the team.
   * @param description The description.
   */
  public void setDescription (String description) {
    this.description = description;    
  }     
  
  /**
   * Retrieves all the files that exist in the .hackystat/avatars/teams directory. 
   * @return The file names in the directory.
   */
  private List<String> getFilesAvailable() {
    List<String> fileNames = new ArrayList<String>();
    String teamLogosDir = System.getProperty("user.home") + "/.hackystat/devcathlon/avatars/team/";
    File logos = new File(teamLogosDir);
    if (logos.isDirectory()) {
      for (File file : logos.listFiles()) {
        fileNames.add(file.getName());
      }
    }
    return fileNames;
  }
}